namespace ObjectPersistence {
    using System;
    using System.Text;
    using System.Collections;
    using System.Data.Common;
    using System.Transactions;
    using System.Collections.Generic;
    
    public partial class CategoryAssembler : AssemblerBaseUpdatable<KYO.DAL.Category, CategoryCriteria, CategoryRowMap, CategoryDomainObjectFactory> {
        public CategoryAssembler() {
            base.connection = new System.Data.SqlClient.SqlConnection(GlobalUtil.Constants.ConnectionString);
        }
        protected override System.Data.Common.DbConnection InstanceConnection {
            get {
                return this.connection;
            }
        }
        /// <summary>Reads a single object from the database corresponding to the object keys which are passed in</summary>
        public KYO.DAL.Category ReadSingleByKey(int CategoryID) {
            CategoryCriteria criteria = new CategoryCriteria();
            criteria.Set_CategoryID(CategoryCriteria.AVAILABLE_OPERATORS.EQUALS, CategoryID);
            return this.ReadSingle(criteria);
        }

        internal override void MakePersistent(KYO.DAL.Category PersistentObject, bool cascade, System.Data.Common.DbCommand comm) {
            if ((PersistentObject.IsNew == false)) {
                if ((GlobalUtil.Constants.ObjectMapKYOPHUONGDOPC.Contains(PersistentObject.ROKeyString) 
                            && (PersistentObject.ChangesMade == false))) {
                    return;
                }
                if ((GlobalUtil.Constants.ObjectMapKYOPHUONGDOPC.Contains(PersistentObject.ROKeyString) == false)) {
                    GlobalUtil.Constants.ObjectMapKYOPHUONGDOPC.Add(PersistentObject.ROKeyString);
                }
            }

            if ((PersistentObject.IsNew || PersistentObject.ChangesMade)) {
                CategoryUpdateFactory updateFactory = new CategoryUpdateFactory();
                comm.Parameters.Clear();
                if ((PersistentObject.IsNew == false)) {
                    updateFactory.updateCommandText(PersistentObject, comm);
                    int numRows = comm.ExecuteNonQuery();
                    if ((numRows == 0)) {
                        throw new NoRowsUpdated();
                    }
                }
                else {
                    updateFactory.insertCommandText(PersistentObject, comm);
                    comm.CommandText = (comm.CommandText + "; SELECT SCOPE_IDENTITY();");
                    decimal NewIdentityKey = ((decimal)(comm.ExecuteScalar()));
                    PersistentObject.CategoryID = ((int)(NewIdentityKey));
                    GlobalUtil.Constants.ObjectMapKYOPHUONGDOPC.Add(PersistentObject.ROKeyString);
                    PersistentObject.IsNew = false;
                }
            }
            PersistentObject.ChangesMade = false;
            if (cascade) {
                InformationAssembler tempInformationAssembler = new InformationAssembler();

                if ((PersistentObject.IsInformationCollNull() == false)) {
                    for (int i1 = 0; (i1 < PersistentObject.InformationColl.Count); i1 = (i1 + 1)) {
                        comm.Parameters.Clear();
                        tempInformationAssembler.MakePersistent(PersistentObject.InformationColl[i1], cascade, comm);
                    }
                    PersistentObject.InformationColl.Clean();
                    this.InsertAddedInformationCollMappingTable(PersistentObject, comm);
                    this.RemoveDeletedInformationCollMappingTableEntries(PersistentObject, comm);
                    PersistentObject.InformationColl.Synch();
                }
                tempInformationAssembler.Dispose();
            }
        }

        internal override void Delete(KYO.DAL.Category PersistentObject, System.Data.Common.DbCommand comm) {
            this.DeleteInformationCollMappingTable(PersistentObject, comm);

            comm.Parameters.Clear();

            CategorySelectionFactory tempCategorySelectionFactory = new CategorySelectionFactory();
            string sql = "DELETE FROM [dbo].[Category]";
            comm.CommandText = sql;
            tempCategorySelectionFactory.getDefaultSelection(PersistentObject, comm);
            comm.ExecuteNonQuery();
        }

        #region Manage Mapping Tables
        private void InsertAddedInformationCollMappingTable(KYO.DAL.Category PersistentObject, System.Data.Common.DbCommand comm) {
            comm.CommandText = "IF NOT EXISTS (SELECT 1 FROM [dbo].[InformationInCategory] (nolock) WHERE [Catego" +
                "ryID] = @larg0 AND [InformationID] = @rarg1) INSERT INTO [dbo].[InformationInCat" +
                "egory] ([CategoryID] , [InformationID] ) VALUES (@larg0, @rarg1)";
            for (int i = 0; (i < PersistentObject.InformationColl.Added.Count); i = (i + 1)) {
                comm.Parameters.Clear();
                ObjectPersistenceHelper.AddParameterWithValue(comm, "@larg0", PersistentObject.CategoryID);
                ObjectPersistenceHelper.AddParameterWithValue(comm, "@rarg1", PersistentObject.InformationColl.Added[i].InformationID);
                comm.ExecuteNonQuery();
            }
        }

        private void DeleteInformationCollMappingTable(KYO.DAL.Category PersistentObject, System.Data.Common.DbCommand comm) {
            comm.Parameters.Clear();
            comm.CommandText = "DELETE FROM [dbo].[InformationInCategory] WHERE [CategoryID]=@arg0";
            ObjectPersistenceHelper.AddParameterWithValue(comm, "@arg0", PersistentObject.CategoryID);
            comm.ExecuteNonQuery();
        }

        private void RemoveDeletedInformationCollMappingTableEntries(KYO.DAL.Category PersistentObject, System.Data.Common.DbCommand comm) {
            comm.CommandText = "DELETE FROM [dbo].[InformationInCategory] WHERE  [CategoryID]=@arg0 AND  [Informa" +
                "tionID]=@rarg1";
            for (int i = 0; (i < PersistentObject.InformationColl.Deleted.Count); i = (i + 1)) {
                comm.Parameters.Clear();
                ObjectPersistenceHelper.AddParameterWithValue(comm, "@arg0", PersistentObject.CategoryID);
                ObjectPersistenceHelper.AddParameterWithValue(comm, "@rarg1", PersistentObject.InformationColl.Deleted[i].InformationID);
                comm.ExecuteNonQuery();
            }
        }
        #endregion

        #region Manage Child Objects / Collections
        /// Reads the KYO.DAL.Information from the database corresponding to the object keys passed as parameters
        // <param name="localCategoryID">Corresponds to Category attribute CategoryID</param
        // <param name="local">Corresponds to Category attribute </param
        public BusinessLayerHelper.PersistentList<KYO.DAL.Information> GetInformationColl(int localCategoryID) {
            BusinessLayerHelper.PersistentList<KYO.DAL.Information> result = new BusinessLayerHelper.PersistentList<KYO.DAL.Information>();
            System.Data.Common.DbConnection tempConnection = this.InstanceConnection;
            try {
                tempConnection.Open();
                System.Data.Common.DbCommand comm = tempConnection.CreateCommand();
                comm.CommandText = (InformationAssembler.SELECT + " FROM [dbo].[InformationInCategory] INNER JOIN [dbo].[Information] ON [dbo].[Info" +
                    "rmationInCategory].[InformationID] = [dbo].[Information].[InformationID] WHERE [" +
                    "dbo].[InformationInCategory].[CategoryID] = @arg1");
                ObjectPersistenceHelper.AddParameterWithValue(comm, "@arg1", localCategoryID);
                InformationAssembler _tempAssem = new InformationAssembler();
                result.FillData(_tempAssem.ReadCollectionCustom(comm));
            }
            finally {
                tempConnection.Close();
            }
            return result;
        }
        #endregion

        #region Helper Utilities
        protected override CategoryRowMap fillRowMap(System.Data.Common.DbDataReader reader) {
            CategoryRowMap result = new CategoryRowMap();
            result.CategoryID = reader.GetInt32(reader.GetOrdinal("dboCategoryDOTCategoryID"));
            result.Title = reader.GetString(reader.GetOrdinal("dboCategoryDOTTitle"));
            result.Odering = reader.GetInt32(reader.GetOrdinal("dboCategoryDOTOdering"));
            result.Published = reader.GetBoolean(reader.GetOrdinal("dboCategoryDOTPublished"));
            return result;
        }
        internal override void ClearList() {
            GlobalUtil.Constants.ObjectMapKYOPHUONGDOPC.Clear();
        }

        public override string Abstract_SELECT {
            get {
                return ("SELECT " + CategoryAssembler.RawFields);
            }
        }
        protected override string InstanceTable {
            get {
                return "[dbo].[Category]";
            }
        }
        public const string RawFields = "[dbo].[Category].[CategoryID] AS dboCategoryDOTCategoryID, [dbo].[Category].[Oder" +
            "ing] AS dboCategoryDOTOdering, [dbo].[Category].[Published] AS dboCategoryDOTPub" +
            "lished, [dbo].[Category].[Title] AS dboCategoryDOTTitle";
        public const string SELECT = "SELECT [dbo].[Category].[CategoryID] AS dboCategoryDOTCategoryID, [dbo].[Category" +
            "].[Odering] AS dboCategoryDOTOdering, [dbo].[Category].[Published] AS dboCategor" +
            "yDOTPublished, [dbo].[Category].[Title] AS dboCategoryDOTTitle";
        #endregion
    }
}
